package com.meiyuetao.myt.pub.web.action;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import lab.s2jh.core.web.SimpleController;

import org.apache.solr.common.SolrDocument;
import org.apache.solr.common.SolrDocumentList;
import org.apache.solr.common.util.SimpleOrderedMap;
import org.apache.struts2.rest.HttpHeaders;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowCallbackHandler;

import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.meiyuetao.myt.core.service.SolrService;

public class CustomerCommodityController extends SimpleController {

    @Autowired
    private SolrService solrService;
    @Autowired
    private JdbcTemplate jdbcTemplate;

    private Long cid;// 客户ID
    private Integer size;// 返回条数
    private Integer mltSize;// guessCustomerLike查询区域（会根据此数值确定查询more like
                            // this的集合数）

    /**
     * 用户浏览过的商品
     * 
     * @return
     */
    public HttpHeaders history() {
        Map<String, Object> jsonMap = Maps.newHashMap();
        if (cid == null) {
            jsonMap.put("code", "1");
            jsonMap.put("message", "Customer sid is null");
        } else {
            List<CommodityVo> commodities = findHistory(cid, size);
            jsonMap.put("code", "0");
            jsonMap.put("message", "SUCCESS");
            jsonMap.put("data", commodities);
        }
        setModel(jsonMap);
        return buildDefaultHttpHeaders();
    }

    /**
     * 猜测用户可能喜欢的商品
     * 
     * @return
     */
    public HttpHeaders guessCustomerLike() {
        Map<String, Object> jsonMap = Maps.newHashMap();
        if (cid == null) {
            jsonMap.put("code", "1");
            jsonMap.put("message", "Customer sid is null");
        } else {
            List<CommodityVo> commodities = guess(cid, size, mltSize);
            jsonMap.put("code", "0");
            jsonMap.put("message", "SUCCESS");
            jsonMap.put("data", commodities);
        }
        setModel(jsonMap);
        return buildDefaultHttpHeaders();
    }

    /**
     * 查询 用户最近浏览过的商品
     * 
     * @param cid
     *            客户SID
     * @param size
     *            返回商品条数
     * @return
     */
    public List<CommodityVo> findHistory(Long cid, Integer size) {
        if (cid == null)
            return null;
        size = size == null ? 5 : size;// 默认TOP5
        String sql = "SELECT " + "TOP " + size + " c.* " + "FROM " + "iyb_commodity_view_stat cvt, " + "iyb_commodity c " + "WHERE " + "cvt.commodity_sid=c.sid "
                + "AND c.commodity_status='S30ONSALE'" + // 在售的
                "AND cvt.customer_profile_sid='" + cid + "' " + "ORDER BY " + "cvt.last_view_time DESC ";
        System.out.println(sql);
        final List<CommodityVo> commodities = Lists.newArrayList();
        jdbcTemplate.query(sql, new RowCallbackHandler() {
            @Override
            public void processRow(ResultSet rs) throws SQLException {
                CommodityVo c = new CommodityVo();
                c.setTitle(rs.getString("title"));// 标题
                c.setCircle(rs.getBoolean("is_circle"));
                c.setId(rs.getLong("sid"));// ID
                c.setCanBuyNow(rs.getBoolean("can_buy_now"));// 是否立即购买
                c.setSmallPic(rs.getString("small_pic"));// 主图
                commodities.add(c);
            }

        });
        return commodities;
    }

    /**
     * 猜测用户可能喜欢的商品
     * 
     * @param cid
     *            客户ID（即CustomerProfile.sid）
     * @param size
     *            返回的商品条数
     * @param mltSize
     *            查询区域（会根据此数值确定more like this的总集合数 和 每个集合的数据条数）
     * @return
     */
    public List<CommodityVo> guess(Long cid, Integer size, Integer mltSize) {
        if (cid == null)
            return null;
        size = size == null ? 5 : size;// 默认TOP5
        mltSize = mltSize == null ? 5 : mltSize;// 默认 5
        // 获取用户最近浏览记录
        List<CommodityVo> his = findHistory(cid, mltSize);
        // 计数用 Map<商品SID, 出现次数>
        Map<Long, Integer> countMap = new java.util.HashMap<Long, Integer>();
        for (CommodityVo commodity : his) {
            /** 1. 根据用户最近的浏览记录，查找类似商品集合（solr mlt） **/
            SimpleOrderedMap<SolrDocumentList> mltResults = solrService.searchCommodities(commodity.getTitle(), 0, mltSize, true);

            /** 2. 循环查找到的 类似商品集合，并计数 **/
            for (int i = 0; i < mltResults.size(); i++) {
                SolrDocumentList items = mltResults.getVal(i);

                for (SolrDocument doc : items) {
                    Long commoditySid = Long.valueOf(doc.getFieldValue("sid").toString());
                    Integer count = countMap.get(commoditySid);
                    if (count == null) {
                        countMap.put(commoditySid, 1);
                    } else {
                        countMap.put(commoditySid, ++count);
                    }
                }
            }
        }

        /** 3. 找出出现次数最多的商品返回 **/
        return getTopByValue(countMap, size);
    }

    /**
     * 返回 map 中出现次数最多的 N 条记录
     * 
     * @param map
     *            map<商品ID，出现次数>
     * @param size
     *            返回记录数(size==null，默认5条)
     * @return
     */
    private List<CommodityVo> getTopByValue(Map<Long, Integer> map, Integer size) {
        List<CommodityVo> result = Lists.newArrayList();
        Map<Long, Integer> sortedMap = sortByValue(map);
        size = size == null ? 5 : size;// 默认TOP5
        int count = 0;
        for (Map.Entry<Long, Integer> entry : sortedMap.entrySet()) {
            Long commodityId = entry.getKey();
            CommodityVo commodity = findOne(commodityId);
            result.add(commodity);
            count++;
            if (count >= size)
                break;
        }
        return result;
    }

    public CommodityVo findOne(Long sid) {
        if (sid == null)
            return null;
        String sql = "SELECT * FROM iyb_commodity c WHERE c.sid='" + sid + "'";
        System.out.println(sql);

        final CommodityVo c = new CommodityVo();
        jdbcTemplate.query(sql, new RowCallbackHandler() {
            @Override
            public void processRow(ResultSet rs) throws SQLException {
                c.setTitle(rs.getString("title"));// 标题
                c.setCircle(rs.getBoolean("is_circle"));
                c.setId(rs.getLong("sid"));// ID
                c.setCanBuyNow(rs.getBoolean("can_buy_now"));// 是否立即购买
                c.setSmallPic(rs.getString("small_pic"));// 主图
            }

        });
        return c;
    }

    /**
     * 根据 Map value 降序排列
     * 
     * @param map
     * @return
     */
    private static <K, V extends Comparable<? super V>> Map<K, V> sortByValue(Map<K, V> map) {
        List<Map.Entry<K, V>> list = new LinkedList<Map.Entry<K, V>>(map.entrySet());
        Collections.sort(list, new Comparator<Map.Entry<K, V>>() {
            public int compare(Map.Entry<K, V> o1, Map.Entry<K, V> o2) {
                return (o1.getValue()).compareTo(o2.getValue()) * -1;
            }
        });

        Map<K, V> result = new LinkedHashMap<K, V>();
        for (Map.Entry<K, V> entry : list) {
            result.put(entry.getKey(), entry.getValue());
        }
        return result;
    }

    public static void main(String[] args) {
        Map<Long, Integer> map = new HashMap<Long, Integer>();

        map.put(1L, 11);
        map.put(8L, 88);
        map.put(3L, 33);
        map.put(2L, 22);
        map.put(2L, 2);

        Map<Long, Integer> smap = CustomerCommodityController.sortByValue(map);
        System.out.println(smap);

    }

    /**************************************/
    public Integer getSize() {
        return size;
    }

    public void setSize(Integer size) {
        this.size = size;
    }

    public Long getCid() {
        return cid;
    }

    public void setCid(Long cid) {
        this.cid = cid;
    }

    public Integer getMltSize() {
        return mltSize;
    }

    public void setMltSize(Integer mltSize) {
        this.mltSize = mltSize;
    }

    /**************************************/
    class CommodityVo {
        private Long id;
        private String title;
        private Boolean circle;
        private Boolean canBuyNow;
        private String smallPic;

        public Long getId() {
            return id;
        }

        public void setId(Long id) {
            this.id = id;
        }

        public String getTitle() {
            return title;
        }

        public void setTitle(String title) {
            this.title = title;
        }

        public Boolean getCircle() {
            return circle;
        }

        public void setCircle(Boolean circle) {
            this.circle = circle;
        }

        public Boolean getCanBuyNow() {
            return canBuyNow;
        }

        public void setCanBuyNow(Boolean canBuyNow) {
            this.canBuyNow = canBuyNow;
        }

        public String getSmallPic() {
            return smallPic;
        }

        public void setSmallPic(String smallPic) {
            this.smallPic = smallPic;
        }

    }
}